package service

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/smartwalle/alipay/v3"
	"go.uber.org/zap"
	"mall-portalv2/conf"
	"mall-portalv2/global"
	"mall-portalv2/internal/model"
	"mall-portalv2/library/common"
)

type AliyunPay struct {
	AppID                   string
	PrivateKey              string
	IsProduction            bool
	AppCertPublicKey        string
	AlipayRootCert          string
	AlipayCertPublicKeyRSA2 string
}

func (payConf AliyunPay) initClient() (*alipay.Client, error) {
	aliClient, err := alipay.New(payConf.AppID, payConf.PrivateKey, payConf.IsProduction)
	if err != nil {
		global.Log.Error("请求参数不正确", zap.Error(err))
		return aliClient, err
	}
	//  加载应用公钥证书
	if err := aliClient.LoadAppPublicCertFromFile(payConf.AppCertPublicKey); err != nil {
		global.Log.Error("加载应用公钥证书错误", zap.Error(err))
		return aliClient, err
	}
	// 加载支付宝根证书
	if err := aliClient.LoadAliPayRootCertFromFile(payConf.AlipayRootCert); err != nil {
		global.Log.Error("加载支付宝根证书错误", zap.Error(err))
		return aliClient, err
	}
	// 加载支付宝公钥证书
	if err := aliClient.LoadAliPayPublicCertFromFile(payConf.AlipayCertPublicKeyRSA2); err != nil {
		global.Log.Error("加载支付宝公钥证书错误", zap.Error(err))
		return aliClient, err
	}
	return aliClient, nil
}

type AliyunCallBackData struct {
	AppId         string `json:"app_id"`
	AuthAppId     string `json:"auth_app_id"`
	NotifyId      string `json:"notify_id"`
	NotifyTime    string `json:"notify_time"`
	NotifyType    string `json:"notify_type"`
	OutTradeNo    string `json:"out_trade_no"`
	ReceiptAmount string `json:"receipt_amount"`
	Sign          string `json:"sign"`
	SignType      string `json:"sign_type"`
	TotalAmount   string `json:"total_amount"`
	TradeNo       string `json:"trade_no"`
	TradeStatus   string `json:"trade_status"`
}

func (s *Service) AliyunTradeRefund(ctx context.Context, Order model.OmsOrder, data model.TradeRefundData, price float64) error {

	global.Log.Info("打印一下要退款的金额", zap.Any("price", price), zap.Any("price", price))

	aliyunCallBackData := AliyunCallBackData{}

	if err := json.Unmarshal([]byte(Order.PaymentData), &aliyunCallBackData); err != nil {
		global.Log.Error("回调信息解析错误", zap.Error(err))
		return err
	}

	var aliyunPay = AliyunPay{
		AppID:                   conf.Config.AliPay.AppID,
		PrivateKey:              conf.Config.AliPay.PrivateKey,
		IsProduction:            conf.Config.AliPay.IsProduction,
		AppCertPublicKey:        conf.Config.AliPay.AppCertPublicKey,
		AlipayRootCert:          conf.Config.AliPay.AlipayRootCert,
		AlipayCertPublicKeyRSA2: conf.Config.AliPay.AlipayCertPublicKey_RSA2,
	}

	aliyunClient, err := aliyunPay.initClient()
	if err != nil {
		global.Log.Error("支付宝客户端初始化失败", zap.Error(err))
		return err
	}

	//aliClient.ap
	//aliClient.appCertSN

	var p = alipay.TradeRefund{
		//AppAuthToken: aliyunPay.AppID,
		OutTradeNo: Order.OrderSn,
		TradeNo:    aliyunCallBackData.TradeNo,
		// HZ01RF001
		OutRequestNo: common.RandHexUp(9),
		RefundAmount: fmt.Sprintf("%.2f", price),
		//RefundAmount: fmt.Sprintf("%v", Order.PayAmount),
		//RefundCurrency: "",
		RefundReason: "用户退款",
		//OperatorId:   "",
		//StoreId:      "",
		//TerminalId:   "",
	}

	temp, err := aliyunClient.URLValues(p)
	if err != nil {
		global.Log.Error("请求参数不正确", zap.Error(err))
		return err
	}
	global.Log.Info("打印一下发送的客户端数据", zap.Any("data", temp))
	result, err := aliyunClient.TradeRefund(p)
	if err != nil {
		global.Log.Error("请求参数不正确", zap.Error(err))
		return err
	}
	global.Log.Info("打印退款结果", zap.Any("result", result))
	// TODO: 解析返回结果，并解析错误情况

	// TODO: 解析是否成功
	if !result.IsSuccess() {
		global.Log.Error("支付宝返回请求参数不正确", zap.Error(err))
		return err
	}

	return nil
}

func (s *Service) AliyunClose(Order model.OmsOrder, TradeNo string) error {

	global.Log.Info("打印一下要废弃订单")
	// 订单状态：0->待付款；1->待发货；2->已发货；3->已完成；4->已关闭；5->无效订单

	//TradeNo := ""
	//if Order.Status == 0 {
	//	TradeNo = Order.OrderSn
	//} else {
	//	aliyunCallBackData := AliyunCallBackData{}
	//
	//	if err := json.Unmarshal([]byte(Order.PaymentData), &aliyunCallBackData); err != nil {
	//		global.Log.Error("回调信息解析错误", zap.Error(err))
	//		return err
	//	}
	//
	//	TradeNo = aliyunCallBackData.TradeNo
	//}

	var aliyunPay = AliyunPay{
		AppID:                   conf.Config.AliPay.AppID,
		PrivateKey:              conf.Config.AliPay.PrivateKey,
		IsProduction:            conf.Config.AliPay.IsProduction,
		AppCertPublicKey:        conf.Config.AliPay.AppCertPublicKey,
		AlipayRootCert:          conf.Config.AliPay.AlipayRootCert,
		AlipayCertPublicKeyRSA2: conf.Config.AliPay.AlipayCertPublicKey_RSA2,
	}

	aliyunClient, err := aliyunPay.initClient()
	if err != nil {
		global.Log.Error("支付宝客户端初始化失败", zap.Error(err))
		return err
	}

	//aliClient.ap
	//aliClient.appCertSN

	var p = alipay.TradeClose{
		OutTradeNo: TradeNo,
		//TradeNo:    TradeNo,
	}

	temp, err := aliyunClient.URLValues(p)
	if err != nil {
		global.Log.Error("请求参数不正确", zap.Error(err))
		return err
	}
	global.Log.Info("打印一下发送的客户端数据", zap.Any("data", temp))
	result, err := aliyunClient.TradeClose(p)
	if err != nil {
		global.Log.Error("请求参数不正确", zap.Error(err))
		return err
	}
	global.Log.Info("打印退款结果", zap.Any("result", result))
	// TODO: 解析返回结果，并解析错误情况

	return nil
}

type TradeRefundResponse struct {
	AlipayTradeRefundResponse struct {
		Code                         string `json:"code"`
		Msg                          string `json:"msg"`
		SubCode                      string `json:"sub_code"`
		SubMsg                       string `json:"sub_msg"`
		TradeNo                      string `json:"trade_no"`
		OutTradeNo                   string `json:"out_trade_no"`
		BuyerLogonId                 string `json:"buyer_logon_id"`
		BuyerUserId                  string `json:"buyer_user_id"`
		FundChange                   string `json:"fund_change"`
		RefundFee                    string `json:"refund_fee"`
		RefundCurrency               string `json:"refund_currency"`
		GmtRefundPay                 string `json:"gmt_refund_pay"`
		StoreName                    string `json:"store_name"`
		RefundSettlementId           string `json:"refund_settlement_id"`
		PresentRefundBuyerAmount     string `json:"present_refund_buyer_amount"`
		PresentRefundDiscountAmount  string `json:"present_refund_discount_amount"`
		PresentRefundMdiscountAmount string `json:"present_refund_mdiscount_amount"`
		SendBackFee                  string `json:"send_back_fee"`
	} `json:"alipay_trade_refund_response"`
	Sign string `json:"sign"`
}
